package com.hancheng.commoncloud.framework.util;


import com.alibaba.fastjson.JSON;
import com.hancheng.commoncloud.framework.result.exception.CommonException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;

/**
 * @ClassName HttpClient
 * @author 金笛
 * @date 2022/1/23 16:05
 * @Description http工具客户端
 * @Version 1.0
 */
@Slf4j
@Component
public class HttpClientUtil {
    @Autowired
    private WebClient webClient;
    /**
     * post请求
     *
     * @param url
     * @param request
     * @param responseType
     */
    public <T> T post(String url, Object request, Class<T> responseType, String messageVar) {
        log.info("{}，接口地址：{}，调用参数：{}", messageVar, url, JSON.toJSONString(request));
        T result;
        try {
            result = webClient.post()
                    .uri(url)
                    .body(BodyInserters.fromObject(request))
                    .retrieve()
                    .bodyToFlux(responseType)
                    .blockFirst();
            log.info("{}, 接口地址：{}，返回数据：{}", messageVar, url, JSON.toJSONString(result));
            return result;
        } catch (Exception e) {
            log.debug("{}失败:{} 接口地址：{}", messageVar, e.getMessage(), url);
            throw new CommonException("网络请求失败");
        }
    }

    /**
     * post请求 (带请求头)
     * @param url
     * @param headersMap
     * @param request
     * @param responseType
     * @param messageVar
     * @param <T>
     * @return
     */
    public <T> T  post(String url, Map<String, String> headersMap, Object request, Class<T> responseType, String messageVar) {
        log.info("{}，接口地址：{}，调用参数：{}", messageVar, url, request);
        try {
            headersMap.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
            Consumer<HttpHeaders> headersConsumer = httpHeaders -> {
                for (Map.Entry<String, String> entry : headersMap.entrySet()) {
                    httpHeaders.add(entry.getKey(), entry.getValue());
                }
            };
            T result = webClient.post()
                    .uri(url)
                    .headers(headersConsumer)
                    .body(BodyInserters.fromObject(request))
                    .retrieve()
                    .bodyToFlux(responseType)
                    .blockFirst();
            log.info("{}, 接口地址：{}，返回数据：{}", messageVar, url, result);
            return result;
        } catch (Exception e) {
            log.error("{}失败:{} 接口地址：{}", messageVar, e.getMessage(), url);
            throw new CommonException("网络请求失败");
        }
    }

    /**
     * post请求 form表单提交
     * @param url
     * @param multiValueMap
     * @param responseType
     * @param messageVar
     * @param <T>
     * @return
     */
    public <T> T  postByFormData(String url, MultiValueMap<String, String> multiValueMap, Class<T> responseType, String messageVar) {
        String trackId = UUID.randomUUID().toString();
        log.info("trackId：[{}]，{}，接口地址：{}，调用参数：{}", trackId, messageVar, url, multiValueMap);
        T result;
        try {
            result = webClient.post()
                    .uri(url)
                    .body(BodyInserters.fromFormData(multiValueMap))
                    .retrieve()
                    .bodyToFlux(responseType)
                    .blockFirst();
            log.info("trackId：[{}]，{}, 接口地址：{}，返回数据：{}", trackId, messageVar, url, JSON.toJSONString(result));
            return result;
        } catch (Exception e) {
            log.debug("trackId：[{}]，{}失败:{} 接口地址：{}", trackId, messageVar, e.getMessage(), url);
            throw new CommonException("网络请求失败");
        }
    }

}
